package ar.edu.untref.lp1.plomeria.tests.unit;

import org.junit.Assert;
import org.junit.Test;

import ar.edu.untref.lp1.plomeria.controladores.PlomeroMatic;
import ar.edu.untref.lp1.plomeria.helpers.HelperParedDeMaterial;
import ar.edu.untref.lp1.plomeria.mapas.gui.controladores.DrawMap;
import ar.edu.untref.lp1.plomeria.modelos.Casillero;
import ar.edu.untref.lp1.plomeria.modelos.Material;
import ar.edu.untref.lp1.plomeria.modelos.Tablero;

public class PlomeroMaticTest {
	
	@Test(expected=Error.class)
	public void validaMatrizDe2x2NullPrimeraColumnaTest() {
		PlomeroMatic plomero = new PlomeroMatic();
		HelperParedDeMaterial helperPared = new HelperParedDeMaterial();
		Material[][] pared = helperPared.getParedDeLadrillos(2,1);
		pared[0][0] = null;
		pared[1][0] = Material.CAÑO_HORIZONTAL;
		
		plomero.construirCañeria(pared);
		helperPared.imprimeMatriz(pared);
		
		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_HORIZONTAL,pared[0][0]);
		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_HORIZONTAL,pared[1][0]);		
	}
	
	@Test(expected=Error.class)
	public void validaMatrizDe2x2NullColumnaIntermediaTest() {
		PlomeroMatic plomero = new PlomeroMatic();
		HelperParedDeMaterial helperPared = new HelperParedDeMaterial();
		Material[][] materparedial = helperPared.getParedDeLadrillos(6,6);
		materparedial[0][0] = Material.CAÑO_HORIZONTAL;
		materparedial[3][2] = null;
		materparedial[5][3] = Material.CAÑO_HORIZONTAL;
		
		plomero.construirCañeria(materparedial);
		helperPared.imprimeMatriz(materparedial);
		
		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_HORIZONTAL,materparedial[0][0]);
		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_HORIZONTAL,materparedial[1][0]);		
	}
	
	/* OJO ACA... una matriz de 2 columnas es ilegal por definicion, 
	 * no tiene columna intermecia entre dos columnas con caños.
	 */
	@Test(expected=Error.class) 
	public void validaMatrizDe2x1ConCañosExtremosTest() {
		PlomeroMatic plomero = new PlomeroMatic();
		HelperParedDeMaterial helperPared = new HelperParedDeMaterial();
		Material[][] pared = helperPared.getParedDeLadrillos(2,1);
		pared[0][0] = Material.CAÑO_HORIZONTAL;
		pared[1][0] = Material.CAÑO_HORIZONTAL;
		
		plomero.construirCañeria(pared);
		helperPared.imprimeMatriz(pared);
		
		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_HORIZONTAL,pared[0][0]);
		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_HORIZONTAL,pared[1][0]);		
	}
	
	@Test
	public void validaMatrizDe3x1ConCañosExtremosTest() {
		PlomeroMatic plomero = new PlomeroMatic();
		HelperParedDeMaterial helperPared = new HelperParedDeMaterial();
		Material[][] pared = helperPared.getParedDeLadrillos(3,1);
		pared[0][0] = Material.CAÑO_HORIZONTAL;
		pared[2][0] = Material.CAÑO_HORIZONTAL;
		
		plomero.construirCañeria(pared);
		helperPared.imprimeMatriz(pared);

		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_HORIZONTAL,pared[0][0]);
		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_HORIZONTAL,pared[1][0]);
		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_HORIZONTAL,pared[2][0]);
	}
	
	@Test
	public void validaMatrizDe3x2ConCañosExtremosTest() {
		PlomeroMatic plomero = new PlomeroMatic();
		HelperParedDeMaterial helperPared = new HelperParedDeMaterial();
		Material[][] pared = helperPared.getParedDeLadrillos(3,2);
		pared[0][0] = Material.CAÑO_HORIZONTAL;
		pared[2][1] = Material.CAÑO_HORIZONTAL;
		
		plomero.construirCañeria(pared);
		helperPared.imprimeMatriz(pared);

		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_HORIZONTAL,pared[0][0]);
		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_ABAJO_IZQUIERDA,pared[1][0]);
		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_ARRIBA_DERECHA,pared[1][1]);
	}
	
	@Test
	public void validaQueModificaElArrayOriginalPorReferenciaTest() {
		PlomeroMatic plomero = new PlomeroMatic();
		HelperParedDeMaterial helperPared = new HelperParedDeMaterial();
		Material[][] pared = helperPared.getParedDeLadrillos(10,5);
		pared[0][0] = Material.CAÑO_HORIZONTAL;
		pared[2][0] = Material.CAÑO_HORIZONTAL;
		pared[6][4] = Material.CAÑO_HORIZONTAL;
		pared[9][2] = Material.CAÑO_HORIZONTAL;
		
		plomero.construirCañeria(pared);
		helperPared.imprimeMatriz(pared);

		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_HORIZONTAL,pared[1][0]);
		Assert.assertEquals("valida el caño codo",
				 Material.CAÑO_ABAJO_IZQUIERDA,pared[3][0]);
		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_VERTICAL,pared[3][1]);
		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_VERTICAL,pared[3][2]);
		Assert.assertEquals("valida el caño codo",
				 Material.CAÑO_ARRIBA_DERECHA,pared[3][4]);
		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_VERTICAL,pared[3][2]);
		Assert.assertEquals("valida el caño codo", 
				Material.CAÑO_VERTICAL,pared[3][2]);
		
	}
	
	@Test
	public void ejecucionCompleta1Test() {
		PlomeroMatic plomero = new PlomeroMatic();
		Material[][] pared = new Material[10][5];
		HelperParedDeMaterial helperPared = new HelperParedDeMaterial();
		pared = helperPared.getParedDeLadrillos(10,5);
		pared[0][0] = Material.CAÑO_HORIZONTAL;
		pared[2][0] = Material.CAÑO_HORIZONTAL;
		pared[6][4] = Material.CAÑO_HORIZONTAL;
		pared[9][2] = Material.CAÑO_HORIZONTAL;
		
		plomero.declararParedDeTrabajo(pared);
		helperPared.imprimeMatriz(plomero.getTrabajo());
		
		plomero.construirCañeria(pared);
		/* imprime la pared  (terminada desde clase plomeromatic) */
		Material[][] paredProcesada = plomero.getTrabajo();
		helperPared.imprimeMatriz(paredProcesada);
		
		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_HORIZONTAL,paredProcesada[1][0]);
		Assert.assertEquals("valida el caño codo",
				 Material.CAÑO_ABAJO_IZQUIERDA,paredProcesada[3][0]);
		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_VERTICAL,paredProcesada[3][1]);
		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_VERTICAL,paredProcesada[3][2]);
		Assert.assertEquals("valida el caño codo",
				 Material.CAÑO_ARRIBA_DERECHA,paredProcesada[3][4]);
		Assert.assertEquals("valida que el caño intermedio sea horizontal",
				 Material.CAÑO_VERTICAL,paredProcesada[3][2]);
		Assert.assertEquals("valida el caño codo", 
				Material.CAÑO_VERTICAL,paredProcesada[3][2]);
	}

	@Test
	public void pruebaCompletaOkTest() {
		PlomeroMatic plomero = new PlomeroMatic();
		Material[][] pared = new Material[5][5];
		HelperParedDeMaterial helperPared = new HelperParedDeMaterial();
		pared = helperPared.getParedDeLadrillos(5,5);
		pared[0][0] = Material.CAÑO_HORIZONTAL;
		pared[2][0] = Material.CAÑO_HORIZONTAL;
		pared[4][4] = Material.CAÑO_HORIZONTAL;
		plomero.declararParedDeTrabajo(pared);
		//plomero.algoritmoDeResolucionDelProblema();
		plomero.ambosCañosEstanEnLaMismaFila(new Casillero(pared[0][0], 0, 0), new Casillero(pared[2][0], 2, 0));
		Material[][] solucion = plomero.getTrabajo();
		
		System.out.println("--- "+solucion[1][0]);
		Assert.assertEquals("valida que el ca�o intermedio sea horizontal",
				solucion[1][0], Material.CAÑO_HORIZONTAL);
	}
	
	@Test (expected = Error.class)
	public void pruebaCompletaPeroSinSeparacionTest() {
		PlomeroMatic plomero = new PlomeroMatic();
		Material[][] pared = new Material[5][5];
		HelperParedDeMaterial helperPared = new HelperParedDeMaterial();
		pared = helperPared.getParedDeLadrillos(5,5);
		pared[0][0] = Material.CAÑO_HORIZONTAL;
		pared[1][0] = Material.CAÑO_HORIZONTAL;
		pared[4][4] = Material.CAÑO_HORIZONTAL;
		Tablero tablero = new Tablero(pared);
		plomero.ambosCañosEstanEnLaMismaFila(tablero.getCasillero(0, 0), tablero.getCasillero(1, 0));
		Assert.assertEquals("valida que el ca�o intermedio sea horizontal",
				tablero.getMaterialCasillero(1, 0), Material.CAÑO_HORIZONTAL);
	}
	
	@Test (expected = Error.class)
	public void esIgualPeroSinSeparacion2Test() {
		PlomeroMatic plomero = new PlomeroMatic();
		Material[][] pared = new Material[5][5];
		HelperParedDeMaterial helperPared = new HelperParedDeMaterial();
		pared = helperPared.getParedDeLadrillos(5,5);
		pared[0][0] = Material.CAÑO_HORIZONTAL;
		pared[3][0] = Material.CAÑO_HORIZONTAL;
		pared[4][4] = Material.CAÑO_HORIZONTAL;
		Tablero tablero = new Tablero(pared);
		plomero.ambosCañosEstanEnLaMismaFila(tablero.getCasillero(0, 0), tablero.getCasillero(1, 0));
		Assert.assertEquals("valida que el ca�o intermedio sea horizontal",
				tablero.getMaterialCasillero(1, 0), Material.CAÑO_HORIZONTAL);
	}

	@Test(expected = Error.class)
	public void resolucion2xN() {
		PlomeroMatic plomero = new PlomeroMatic();
		Material[][] pared = new Material[2][5];
		HelperParedDeMaterial helperPared = new HelperParedDeMaterial();
		pared = helperPared.getParedDeLadrillos(2,5);
		pared[0][0] = Material.CAÑO_HORIZONTAL;
		pared[1][0] = Material.CAÑO_HORIZONTAL;
		plomero.construirCañeria(pared);
	}
	@Test
	public void resolucionNx1() {
		PlomeroMatic plomero = new PlomeroMatic();
		Material[][] pared = new Material[3][1];
		HelperParedDeMaterial helperPared = new HelperParedDeMaterial();
		pared = helperPared.getParedDeLadrillos(3,1);
		pared[0][0] = Material.CAÑO_HORIZONTAL;
		pared[2][0] = Material.CAÑO_HORIZONTAL;
		plomero.construirCañeria(pared);
	}
	@Test
	public void resolucion1xN() {
		PlomeroMatic plomero = new PlomeroMatic();
		Material[][] pared = new Material[1][1];
		HelperParedDeMaterial helperPared = new HelperParedDeMaterial();
		pared = helperPared.getParedDeLadrillos(1,1);
		pared[0][0] = Material.CAÑO_HORIZONTAL;
		//material[2][0] = Material.CAÑO_HORIZONTAL;
		plomero.construirCañeria(pared);
	}
	@Test
	public void resolucion1x20() {
		PlomeroMatic plomero = new PlomeroMatic();
		Material[][] pared = new Material[1][20];
		HelperParedDeMaterial helperPared = new HelperParedDeMaterial();
		pared = helperPared.getParedDeLadrillos(1,1);
		pared[0][0] = Material.CAÑO_HORIZONTAL;
		//material[2][0] = Material.CAÑO_HORIZONTAL;
		plomero.construirCañeria(pared);
	}
	@Test(expected=Error.class)
	public void resolucionNx2conNMenorA3() {
		PlomeroMatic plomero = new PlomeroMatic();
		Material[][] pared = new Material[2][2];
		HelperParedDeMaterial helperPared = new HelperParedDeMaterial();
		pared = helperPared.getParedDeLadrillos(2,2);
		pared[0][0] = Material.CAÑO_HORIZONTAL;
		pared[1][1] = Material.CAÑO_HORIZONTAL;
		plomero.construirCañeria(pared);
	}
	@Test
	public void resolucionNx2conNMayorOIgualA3() {
		PlomeroMatic plomero = new PlomeroMatic();
		Material[][] pared = new Material[3][2];
		HelperParedDeMaterial helperPared = new HelperParedDeMaterial();
		pared = helperPared.getParedDeLadrillos(3,2);
		pared[0][0] = Material.CAÑO_HORIZONTAL;
		pared[2][1] = Material.CAÑO_HORIZONTAL;
		plomero.construirCañeria(pared);
	}
	
	
	
	

}
